package election

import (
	"context"
	"fmt"
	"math/rand"
	"net/http"
	"sync"
	"time"
)

// ElectionState 表示选举状态
type ElectionState int

const (
	// ElectionStateFollower 表示跟随者状态
	ElectionStateFollower ElectionState = iota
	// ElectionStateCandidate 表示候选者状态
	ElectionStateCandidate
	// ElectionStateLeader 表示领导者状态
	ElectionStateLeader
)

// String 返回选举状态的字符串表示
func (s ElectionState) String() string {
	switch s {
	case ElectionStateFollower:
		return "follower"
	case ElectionStateCandidate:
		return "candidate"
	case ElectionStateLeader:
		return "leader"
	default:
		return "unknown"
	}
}

// ElectionEvent 表示选举事件
type ElectionEvent int

const (
	// ElectionEventBecomeFollower 表示成为跟随者事件
	ElectionEventBecomeFollower ElectionEvent = iota
	// ElectionEventBecomeCandidate 表示成为候选者事件
	ElectionEventBecomeCandidate
	// ElectionEventBecomeLeader 表示成为领导者事件
	ElectionEventBecomeLeader
	// ElectionEventLeaderChanged 表示领导者变更事件
	ElectionEventLeaderChanged
	// ElectionEventTermChanged 表示任期变更事件
	ElectionEventTermChanged
)

// String 返回选举事件的字符串表示
func (e ElectionEvent) String() string {
	switch e {
	case ElectionEventBecomeFollower:
		return "become_follower"
	case ElectionEventBecomeCandidate:
		return "become_candidate"
	case ElectionEventBecomeLeader:
		return "become_leader"
	case ElectionEventLeaderChanged:
		return "leader_changed"
	case ElectionEventTermChanged:
		return "term_changed"
	default:
		return "unknown"
	}
}

// ElectionEventHandler 表示选举事件处理器
type ElectionEventHandler interface {
	// HandleElectionEvent 处理选举事件
	HandleElectionEvent(event ElectionEvent, data map[string]interface{})
}

// ElectionConfig 表示选举配置
type ElectionConfig struct {
	// NodeID 是节点ID
	NodeID string
	// ClusterID 是集群ID
	ClusterID string
	// ElectionTimeout 是选举超时时间
	ElectionTimeout time.Duration
	// HeartbeatInterval 是心跳间隔时间
	HeartbeatInterval time.Duration
	// MaxTerms 是最大任期数
	MaxTerms uint64
	// MinVotes 是最小投票数
	MinVotes int
}

// DefaultElectionConfig 返回默认选举配置
func DefaultElectionConfig() *ElectionConfig {
	return &ElectionConfig{
		ElectionTimeout:   time.Second * 5,
		HeartbeatInterval: time.Second,
		MaxTerms:          0, // 0表示无限制
		MinVotes:          1,
	}
}

// ElectionTransport 表示选举传输接口
type ElectionTransport interface {
	// RequestVote 请求投票
	RequestVote(ctx context.Context, term uint64, candidateID string) (bool, uint64, error)
	// SendHeartbeat 发送心跳
	SendHeartbeat(ctx context.Context, term uint64, leaderID string) error
	// BroadcastLeader 广播领导者
	BroadcastLeader(ctx context.Context, term uint64, leaderID string) error
}

// LeaderElection 表示领导者选举
type LeaderElection struct {
	// config 是选举配置
	config *ElectionConfig
	// transport 是选举传输
	transport ElectionTransport
	// state 是选举状态
	state ElectionState
	// currentTerm 是当前任期
	currentTerm uint64
	// votedFor 是投票对象
	votedFor string
	// currentLeader 是当前领导者
	currentLeader string
	// lastHeartbeat 是最后心跳时间
	lastHeartbeat time.Time
	// electionTimeout 是选举超时时间
	electionTimeout time.Duration
	// handlers 是事件处理器列表
	handlers []ElectionEventHandler
	// mu 是互斥锁
	mu sync.RWMutex
	// ctx 是上下文
	ctx context.Context
	// cancel 是取消函数
	cancel context.CancelFunc
	// wg 是等待组
	wg sync.WaitGroup
}

// NewLeaderElection 创建一个新的领导者选举
func NewLeaderElection(config *ElectionConfig, transport ElectionTransport) *LeaderElection {
	if config == nil {
		config = DefaultElectionConfig()
	}

	ctx, cancel := context.WithCancel(context.Background())

	return &LeaderElection{
		config:          config,
		transport:       transport,
		state:           ElectionStateFollower,
		currentTerm:     0,
		votedFor:        "",
		currentLeader:   "",
		lastHeartbeat:   time.Now(),
		electionTimeout: randomTimeout(config.ElectionTimeout),
		handlers:        make([]ElectionEventHandler, 0),
		ctx:             ctx,
		cancel:          cancel,
	}
}

// Start 启动选举
func (e *LeaderElection) Start() error {
	e.mu.Lock()
	defer e.mu.Unlock()

	// 启动选举循环
	e.wg.Add(1)
	go e.electionLoop()

	// 如果是领导者，启动心跳循环
	if e.state == ElectionStateLeader {
		e.wg.Add(1)
		go e.heartbeatLoop()
	}

	return nil
}

// Stop 停止选举
func (e *LeaderElection) Stop() error {
	e.mu.Lock()
	defer e.mu.Unlock()

	// 取消上下文
	e.cancel()

	// 等待所有协程结束
	e.wg.Wait()

	return nil
}

// AddEventHandler 添加事件处理器
func (e *LeaderElection) AddEventHandler(handler ElectionEventHandler) {
	e.mu.Lock()
	defer e.mu.Unlock()
	e.handlers = append(e.handlers, handler)
}

// RemoveEventHandler 移除事件处理器
func (e *LeaderElection) RemoveEventHandler(handler ElectionEventHandler) bool {
	e.mu.Lock()
	defer e.mu.Unlock()

	for i, h := range e.handlers {
		if h == handler {
			e.handlers = append(e.handlers[:i], e.handlers[i+1:]...)
			return true
		}
	}
	return false
}

// GetState 获取选举状态
func (e *LeaderElection) GetState() ElectionState {
	e.mu.RLock()
	defer e.mu.RUnlock()
	return e.state
}

// GetCurrentTerm 获取当前任期
func (e *LeaderElection) GetCurrentTerm() uint64 {
	e.mu.RLock()
	defer e.mu.RUnlock()
	return e.currentTerm
}

// GetCurrentLeader 获取当前领导者
func (e *LeaderElection) GetCurrentLeader() string {
	e.mu.RLock()
	defer e.mu.RUnlock()
	return e.currentLeader
}

// IsLeader 检查是否是领导者
func (e *LeaderElection) IsLeader() bool {
	e.mu.RLock()
	defer e.mu.RUnlock()
	return e.state == ElectionStateLeader
}

// RequestVote 处理投票请求
func (e *LeaderElection) RequestVote(term uint64, candidateID string) (bool, uint64) {
	e.mu.Lock()
	defer e.mu.Unlock()

	// 如果请求的任期小于当前任期，拒绝投票
	if term < e.currentTerm {
		return false, e.currentTerm
	}

	// 如果请求的任期大于当前任期，转换为跟随者
	if term > e.currentTerm {
		e.becomeFollower(term, "")
	}

	// 如果还没有投票或者已经投票给了请求的候选者，投票
	if e.votedFor == "" || e.votedFor == candidateID {
		e.votedFor = candidateID
		e.lastHeartbeat = time.Now()
		return true, e.currentTerm
	}

	return false, e.currentTerm
}

// ReceiveHeartbeat 接收心跳
func (e *LeaderElection) ReceiveHeartbeat(term uint64, leaderID string) bool {
	e.mu.Lock()
	defer e.mu.Unlock()

	// 如果心跳的任期小于当前任期，拒绝心跳
	if term < e.currentTerm {
		return false
	}

	// 如果心跳的任期大于当前任期，转换为跟随者
	if term > e.currentTerm {
		e.becomeFollower(term, leaderID)
	} else if e.state != ElectionStateFollower {
		// 如果心跳的任期等于当前任期，但不是跟随者，转换为跟随者
		e.becomeFollower(term, leaderID)
	} else {
		// 更新领导者和心跳时间
		if e.currentLeader != leaderID {
			e.currentLeader = leaderID
			e.triggerEvent(ElectionEventLeaderChanged, map[string]interface{}{
				"term":      e.currentTerm,
				"leader_id": leaderID,
			})
		}
		e.lastHeartbeat = time.Now()
	}

	return true
}

// electionLoop 选举循环
func (e *LeaderElection) electionLoop() {
	defer e.wg.Done()

	for {
		select {
		case <-e.ctx.Done():
			return
		case <-time.After(e.getElectionTimeout()):
			e.checkElection()
		}
	}
}

// heartbeatLoop 心跳循环
func (e *LeaderElection) heartbeatLoop() {
	defer e.wg.Done()

	ticker := time.NewTicker(e.config.HeartbeatInterval)
	defer ticker.Stop()

	for {
		select {
		case <-e.ctx.Done():
			return
		case <-ticker.C:
			e.sendHeartbeat()
		}
	}
}

// checkElection 检查选举
func (e *LeaderElection) checkElection() {
	e.mu.Lock()

	// 如果是领导者，不需要检查选举
	if e.state == ElectionStateLeader {
		e.mu.Unlock()
		return
	}

	// 检查是否超时
	if time.Since(e.lastHeartbeat) < e.electionTimeout {
		e.mu.Unlock()
		return
	}

	// 转换为候选者
	e.becomeCandidate()
	term := e.currentTerm
	e.mu.Unlock()

	// 开始选举
	e.startElection(term)
}

// startElection 开始选举
func (e *LeaderElection) startElection(term uint64) {
	// 创建上下文
	ctx, cancel := context.WithTimeout(e.ctx, e.config.ElectionTimeout)
	defer cancel()

	// 请求投票
	votes := 1 // 自己的一票
	granted, newTerm, err := e.transport.RequestVote(ctx, term, e.config.NodeID)
	if err != nil {
		fmt.Printf("Failed to request vote: %v\n", err)
		return
	}

	e.mu.Lock()
	defer e.mu.Unlock()

	// 如果任期已经变化，放弃选举
	if term != e.currentTerm {
		return
	}

	// 如果收到了更高的任期，转换为跟随者
	if newTerm > e.currentTerm {
		e.becomeFollower(newTerm, "")
		return
	}

	// 统计票数
	if granted {
		votes++
	}

	// 如果获得足够的票数，成为领导者
	if votes >= e.config.MinVotes {
		e.becomeLeader()
	}
}

// sendHeartbeat 发送心跳
func (e *LeaderElection) sendHeartbeat() {
	e.mu.RLock()
	if e.state != ElectionStateLeader {
		e.mu.RUnlock()
		return
	}
	term := e.currentTerm
	e.mu.RUnlock()

	// 创建上下文
	ctx, cancel := context.WithTimeout(e.ctx, e.config.HeartbeatInterval)
	defer cancel()

	// 发送心跳
	err := e.transport.SendHeartbeat(ctx, term, e.config.NodeID)
	if err != nil {
		fmt.Printf("Failed to send heartbeat: %v\n", err)
	}
}

// becomeFollower 转换为跟随者
func (e *LeaderElection) becomeFollower(term uint64, leaderID string) {
	// 更新状态
	oldState := e.state
	oldTerm := e.currentTerm
	oldLeader := e.currentLeader

	e.state = ElectionStateFollower
	e.currentTerm = term
	e.votedFor = ""
	e.currentLeader = leaderID
	e.lastHeartbeat = time.Now()
	e.electionTimeout = randomTimeout(e.config.ElectionTimeout)

	// 触发事件
	if oldState != ElectionStateFollower {
		e.triggerEvent(ElectionEventBecomeFollower, map[string]interface{}{
			"term":      term,
			"leader_id": leaderID,
		})
	}
	if oldTerm != term {
		e.triggerEvent(ElectionEventTermChanged, map[string]interface{}{
			"old_term": oldTerm,
			"new_term": term,
		})
	}
	if oldLeader != leaderID && leaderID != "" {
		e.triggerEvent(ElectionEventLeaderChanged, map[string]interface{}{
			"term":      term,
			"leader_id": leaderID,
		})
	}
}

// becomeCandidate 转换为候选者
func (e *LeaderElection) becomeCandidate() {
	// 更新状态
	oldState := e.state
	oldTerm := e.currentTerm

	e.state = ElectionStateCandidate
	e.currentTerm++
	e.votedFor = e.config.NodeID
	e.currentLeader = ""
	e.electionTimeout = randomTimeout(e.config.ElectionTimeout)

	// 触发事件
	if oldState != ElectionStateCandidate {
		e.triggerEvent(ElectionEventBecomeCandidate, map[string]interface{}{
			"term": e.currentTerm,
		})
	}
	if oldTerm != e.currentTerm {
		e.triggerEvent(ElectionEventTermChanged, map[string]interface{}{
			"old_term": oldTerm,
			"new_term": e.currentTerm,
		})
	}
}

// becomeLeader 转换为领导者
func (e *LeaderElection) becomeLeader() {
	// 更新状态
	oldState := e.state
	oldLeader := e.currentLeader

	e.state = ElectionStateLeader
	e.currentLeader = e.config.NodeID
	e.lastHeartbeat = time.Now()

	// 触发事件
	if oldState != ElectionStateLeader {
		e.triggerEvent(ElectionEventBecomeLeader, map[string]interface{}{
			"term": e.currentTerm,
		})
	}
	if oldLeader != e.config.NodeID {
		e.triggerEvent(ElectionEventLeaderChanged, map[string]interface{}{
			"term":      e.currentTerm,
			"leader_id": e.config.NodeID,
		})
	}

	// 广播领导者
	ctx, cancel := context.WithTimeout(e.ctx, e.config.HeartbeatInterval)
	defer cancel()
	err := e.transport.BroadcastLeader(ctx, e.currentTerm, e.config.NodeID)
	if err != nil {
		fmt.Printf("Failed to broadcast leader: %v\n", err)
	}

	// 启动心跳循环
	e.wg.Add(1)
	go e.heartbeatLoop()
}

// triggerEvent 触发事件
func (e *LeaderElection) triggerEvent(event ElectionEvent, data map[string]interface{}) {
	for _, handler := range e.handlers {
		handler.HandleElectionEvent(event, data)
	}
}

// getElectionTimeout 获取选举超时时间
func (e *LeaderElection) getElectionTimeout() time.Duration {
	e.mu.RLock()
	defer e.mu.RUnlock()
	return e.electionTimeout
}

// randomTimeout 生成随机超时时间
func randomTimeout(base time.Duration) time.Duration {
	// 生成[base, 2*base)范围内的随机时间
	return base + time.Duration(rand.Int63n(int64(base)))
}

// HTTPElectionTransport 表示HTTP选举传输
type HTTPElectionTransport struct {
	// baseURL 是基础URL
	baseURL string
	// client 是HTTP客户端
	client *http.Client
	// voteRequests 是投票请求通道
	voteRequests chan *VoteRequest
	// voteResponses 是投票响应通道
	voteResponses chan *VoteResponse
	// heartbeats 是心跳通道
	heartbeats chan *Heartbeat
}

// VoteRequest 表示投票请求
type VoteRequest struct {
	// Term 是任期
	Term uint64
	// CandidateID 是候选者ID
	CandidateID string
}

// VoteResponse 表示投票响应
type VoteResponse struct {
	// Granted 是是否授予投票
	Granted bool
	// Term 是任期
	Term uint64
}

// Heartbeat 表示心跳
type Heartbeat struct {
	// Term 是任期
	Term uint64
	// LeaderID 是领导者ID
	LeaderID string
}

// NewHTTPElectionTransport 创建一个新的HTTP选举传输
func NewHTTPElectionTransport(baseURL string) *HTTPElectionTransport {
	return &HTTPElectionTransport{
		baseURL:       baseURL,
		client:        &http.Client{},
		voteRequests:  make(chan *VoteRequest, 100),
		voteResponses: make(chan *VoteResponse, 100),
		heartbeats:    make(chan *Heartbeat, 100),
	}
}

// RequestVote 请求投票
func (t *HTTPElectionTransport) RequestVote(ctx context.Context, term uint64, candidateID string) (bool, uint64, error) {
	// 在实际实现中，这里应该通过HTTP请求投票
	// 为了测试，我们直接发送到投票请求通道
	select {
	case t.voteRequests <- &VoteRequest{Term: term, CandidateID: candidateID}:
	case <-ctx.Done():
		return false, 0, ctx.Err()
	}

	// 等待响应
	select {
	case resp := <-t.voteResponses:
		return resp.Granted, resp.Term, nil
	case <-ctx.Done():
		return false, 0, ctx.Err()
	}
}

// SendHeartbeat 发送心跳
func (t *HTTPElectionTransport) SendHeartbeat(ctx context.Context, term uint64, leaderID string) error {
	// 在实际实现中，这里应该通过HTTP发送心跳
	// 为了测试，我们直接发送到心跳通道
	select {
	case t.heartbeats <- &Heartbeat{Term: term, LeaderID: leaderID}:
		return nil
	case <-ctx.Done():
		return ctx.Err()
	}
}

// BroadcastLeader 广播领导者
func (t *HTTPElectionTransport) BroadcastLeader(ctx context.Context, term uint64, leaderID string) error {
	// 在实际实现中，这里应该通过HTTP广播领导者
	// 为了测试，我们直接发送到心跳通道
	select {
	case t.heartbeats <- &Heartbeat{Term: term, LeaderID: leaderID}:
		return nil
	case <-ctx.Done():
		return ctx.Err()
	}
}
